﻿using MS.Cache;
using MS.DataAccess;
using MS.Entities;
using MS.Enums.Common;
using MS.Utility.Common;
using MS.Utility.Config;
using Newtonsoft.Json;
using ServiceStack.Caching;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Security;

namespace MS.Identity
{
    public class SecurityIdentity
    {
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="uid">用户uid</param>
        /// <param name="platform">登录平台</param>
        public static void Login(long uid, Platform platform = Platform.BMS)
        {
            string key = GetLoginCookieKeyByPlatform(platform);
            HttpCookie cookie = new HttpCookie(key);
            string EncryptKey = ConfigSetting.EncryptKey;
            UserModel model = new UserModel
            {
                uid = uid,
                time = DateTimeHelper.GetTime(DateTime.Now)
            };
            string strModel = JsonConvert.SerializeObject(model);

            cookie.Value = Utils.AESEncrypt(strModel, EncryptKey);
            cookie.Path = ConfigSetting.CookiePath;
            HttpContext.Current.Response.Cookies.Add(cookie);
            //缓存用户登录信息
            GetLoginUser(platform);
        }

        /// <summary>
        /// 获取登录的用户信息
        /// </summary>
        public static LoginUser GetLoginUser(Platform platform = Platform.BMS)
        {
            string key = CacheConfig.LoginUserKey;
            key += GetLoginUid(platform).ToString();

            if (CacheAdapter.Cache.Get<LoginUser>(key) != null)
            {
                return CacheAdapter.Cache.Get<LoginUser>(key);
            }
            else
            {
                MS_UserCenter_UserAccountDataAccess userAccountDataAccess = new MS_UserCenter_UserAccountDataAccess();
                MS_UserCenter_UserAttrDataAccess userAttrDataAccess = new MS_UserCenter_UserAttrDataAccess();
                MS_Base_FunctionDataAccess functionDataAccess = new MS_Base_FunctionDataAccess();
                MS_Base_RoleFunctionDataAccess roleFunctionDataAccess = new MS_Base_RoleFunctionDataAccess();
                MS_Base_RoleDataAccess roleDataAccess = new MS_Base_RoleDataAccess();
                MS_Base_UserRoleDataAccess userRoleDataAccess = new MS_Base_UserRoleDataAccess();
                long uid = GetLoginUid(platform);
                LoginUser loginUser = new LoginUser();
                loginUser.UserAccount = userAccountDataAccess.GetItemByQuery(x => x.Uid == uid && x.Status > (int)UserStatus.Delete);
                loginUser.UserAttr = userAttrDataAccess.GetItemByQuery(x => x.Uid == uid && x.Status > (int)UserStatus.Delete);
                List<MS_Base_UserRole> userRoleList = userRoleDataAccess.GetListByQuery(x => x.Uid == uid && x.Status == (int)Status.Normal, null, false);
                List<int> roleIds = (from o in userRoleList select o.RoleId).ToList();
                loginUser.RoleList = roleDataAccess.GetListByQuery(x => roleIds.Contains(x.Id) && x.Status == (int)RoleStatus.Normal, null, false);
                if (loginUser.RoleList != null && loginUser.RoleList.Count>0)
                {
                    loginUser.CurrentRole = loginUser.RoleList.First();
                    List<MS_Base_RoleFunction> roleFunctionList = roleFunctionDataAccess.GetListByQuery(x => x.RoleId == loginUser.CurrentRole.Id && x.Status == (int)Status.Normal, null, false);
                    List<int> functionIds = (from o in roleFunctionList select o.FunctionId).ToList();
                    loginUser.FunctionList = functionDataAccess.GetListByQuery(x => functionIds.Contains(x.Id) && x.Status == (int)Status.Normal, null, false);
                }
                CacheAdapter.Cache.Add(key, loginUser,new TimeSpan(1,0,0,0));
                return loginUser;
            }
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        public static void Logout(Platform platform = Platform.BMS)
        {
            string cookieKey = GetLoginCookieKeyByPlatform(platform);
            string key = CacheConfig.LoginUserKey;
            key += GetLoginCookieKeyByPlatform(platform) + ":" + GetLoginUid(platform).ToString();
            CacheAdapter.Cache.Remove(key);
            if(HttpContext.Current.Response.Cookies[cookieKey] != null)
            {
                HttpContext.Current.Response.Cookies[cookieKey].Expires = DateTime.Now.AddDays(-1);
            }

        }

        /// <summary>
        /// 获取登录的用户Uid，如果Uid为0代变未登录
        /// </summary>
        /// <param name="platform"></param>
        /// <returns></returns>
        public static long GetLoginUid(Platform platform = Platform.BMS)
        {
            long nLoginUid = 0;
            string key = GetLoginCookieKeyByPlatform(platform);
            string EncryptKey = ConfigSetting.EncryptKey;
            switch (platform)
            {
                case Platform.BMS:

                    HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(key);
                    if (cookie != null)
                    {
                        string o = Utils.AESDecrypt(cookie.Value, EncryptKey);
                        try
                        {
                            UserModel model = JsonConvert.DeserializeObject<UserModel>(o);
                            nLoginUid = model.uid;
                        }
                        catch
                        {

                        }
                    }
                    break;
            }
            return nLoginUid;
        }
        /// <summary>
        /// 获取Cookie中记录用户登录token的Key值
        /// </summary>
        /// <param name="platform"></param>
        /// <returns></returns>
        private static string GetLoginCookieKeyByPlatform(Platform platform)
        {
            string key = "";
            switch (platform)
            {
                case Platform.BMS:
                    key = "bmsusertoken";
                    break;
            }
            return key;
        }
    }

    public class UserModel
    {
        public long uid { get; set; }
        public long time { get; set; }

    }

}
